package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import server.AdminServer;
import server.Cell;
import server.PlayerServer;
import server.Server;

public class FileBarPanel extends JPanel {
	
	private MainWindow mainFrame;
	private UserType user;
	private WorldViewPanel view;

	private Server viewServer;
	private PlayerServer playerServer;
	private AdminServer adminServer;
	
	private JPanel leftPanel;
	private JPanel rightPanel;
	private JButton viewLineageButton;
	private JButton viewProgramButton;
	private JButton loadWorldButton;
	private JButton resetButton;
	private JButton addCritterButton;
	private JButton listCritterFilesButton;
	private JButton changeViewButton;
	private JButton logInOutButton;
	private JButton requestAdminButton;
	private JButton requestUserButton;
	
	private final Color bkg = new Color(255,99,71);

	public FileBarPanel(UserType u, Server server, MainWindow m, WorldViewPanel v) {
		mainFrame = m;
		view = v;
		user = u;
		if(user == UserType.ADMIN || user == UserType.USER_ADMIN)
			adminServer = (AdminServer) server;
		else if(user == UserType.USER)
			playerServer = (PlayerServer) server;
		else
			viewServer = server;
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		add(leftPanel);
		add(rightPanel);
		makeButtons();
		leftPanel.setBackground(bkg);
		rightPanel.setBackground(bkg);
	}

	private void makeButtons() {
		if(user == UserType.ADMIN){	
			viewProgramButton = new JButton("View Program");
			viewProgramButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<String, Object> displayer = new SwingWorker<String, Object>(){
							protected String doInBackground() throws Exception {
								return adminServer.getCritterProgram(c.critId());
							}
							protected void done(){
								try{
									new GenomeDisplayFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewProgramButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			loadWorldButton = new JButton("Load World");
			loadWorldButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new LoadWorldFrame(mainFrame, adminServer);
				}
			});
			resetButton = new JButton("Reset World");
			resetButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					SwingWorker<Object, Object> resetter = new SwingWorker<Object, Object>(){
						protected Object doInBackground() throws Exception {
							adminServer.resetSim();
							return null;
						}
						protected void done(){
							try{
								get();
								view.repaint();
							} catch (Exception e1) {
								JOptionPane.showMessageDialog(SwingUtilities.getRootPane(resetButton),
										e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
							}
						}
					};
					resetter.execute();
				}
			});
			addCritterButton = new JButton("Add Critter");
			addCritterButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new AddCritterFrame(adminServer, view);
				}
			});
			listCritterFilesButton = new JButton("List Critter Files");
			listCritterFilesButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					SwingWorker<String[], Object> lister = new SwingWorker<String[], Object>(){
						protected String[] doInBackground() throws Exception {
							return adminServer.listCritterFiles();
						}
						protected void done(){
							try{
								new CritterFilesFrame(get());
							} catch (Exception e1) {
								JOptionPane.showMessageDialog(SwingUtilities.getRootPane(listCritterFilesButton),
										e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
							}
						}
					};
					lister.execute();
				}
			});
			changeViewButton = new JButton("Show User View");
			changeViewButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					mainFrame.switchAdminView();
				}
			});
			viewLineageButton = new JButton("View Lineage");
			viewLineageButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<int[], Object> displayer = new SwingWorker<int[], Object>(){
							protected int[] doInBackground() throws Exception {
								return adminServer.getLineage(c.speciesId());
							}
							protected void done(){
								try{
									new LineageFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewLineageButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
		} else if (user == UserType.USER_ADMIN){
			viewProgramButton = new JButton("View Program");
			viewProgramButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<String, Object> displayer = new SwingWorker<String, Object>(){
							protected String doInBackground() throws Exception {
								return adminServer.getCritterProgram(c.critId());
							}
							protected void done(){
								try{
									new GenomeDisplayFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewProgramButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			addCritterButton = new JButton("Add Critter");
			addCritterButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new AddCritterFrame(adminServer, view);
				}
			});
			changeViewButton = new JButton("Show Admin View");
			changeViewButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					mainFrame.switchAdminView();
				}
			});
			viewLineageButton = new JButton("View Lineage");
			viewLineageButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<int[], Object> displayer = new SwingWorker<int[], Object>(){
							protected int[] doInBackground() throws Exception {
								return adminServer.getLineage(c.speciesId());
							}
							protected void done(){
								try{
									new LineageFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewLineageButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
		} else if(user == UserType.USER){
			viewProgramButton = new JButton("View Program");
			viewProgramButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<String, Object> displayer = new SwingWorker<String, Object>(){
							protected String doInBackground() throws Exception {
								return playerServer.getCritterProgram(c.critId());
							}
							protected void done(){
								try{
									new GenomeDisplayFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewProgramButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			addCritterButton = new JButton("Add Critter");
			addCritterButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new AddCritterFrame(playerServer, view);
				}
			});
			viewLineageButton = new JButton("View Lineage");
			viewLineageButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<int[], Object> displayer = new SwingWorker<int[], Object>(){
							protected int[] doInBackground() throws Exception {
								return playerServer.getLineage(c.speciesId());
							}
							protected void done(){
								try{
									new LineageFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewLineageButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			requestAdminButton = new JButton("Request Admin Access");
			requestAdminButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new RequestAdminFrame(mainFrame, playerServer);
				}
			});
		}
		if (user == UserType.VIEW) {
			viewProgramButton = new JButton("View Program");
			viewProgramButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<String, Object> displayer = new SwingWorker<String, Object>(){
							protected String doInBackground() throws Exception {
								return viewServer.getCritterProgram(c.critId());
							}
							protected void done(){
								try{
									new GenomeDisplayFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewProgramButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			logInOutButton = new JButton("Log In");
			logInOutButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new LogInFrame(mainFrame, viewServer);
				}
			});
			viewLineageButton = new JButton("View Lineage");
			viewLineageButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					final Cell c = view.getSelectedCell();
					if(c != null && c.hasCritter()){
						SwingWorker<int[], Object> displayer = new SwingWorker<int[], Object>(){
							protected int[] doInBackground() throws Exception {
								return viewServer.getLineage(c.speciesId());
							}
							protected void done(){
								try{
									new LineageFrame(get());
								} catch (Exception e1) {
									JOptionPane.showMessageDialog(SwingUtilities.getRootPane(viewLineageButton),
											e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
								}
							}
						};
						displayer.execute();
					}
				}
			});
			requestUserButton = new JButton("Request User Access");
			requestUserButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new RequestUserFrame(mainFrame, viewServer);
				}
			});
			requestAdminButton = new JButton("Request Admin Access");
			requestAdminButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					new RequestAdminFrame(mainFrame, viewServer);
				}
			});
		} else {
			logInOutButton = new JButton("Log Out");
			logInOutButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					mainFrame.changeUser(null, UserType.VIEW);
				}
			});
		}
		

		switch(user) {
		case ADMIN:
			leftPanel.add(viewLineageButton);
			leftPanel.add(viewProgramButton);
			leftPanel.add(addCritterButton);
			leftPanel.add(listCritterFilesButton);
			leftPanel.add(resetButton);
			leftPanel.add(loadWorldButton);
			rightPanel.add(changeViewButton);
			rightPanel.add(logInOutButton);
			break;
		case USER_ADMIN:
			leftPanel.add(viewLineageButton);
			leftPanel.add(viewProgramButton);
			leftPanel.add(addCritterButton);
			rightPanel.add(changeViewButton);
			rightPanel.add(logInOutButton);
			break;
		case USER:
			leftPanel.add(viewLineageButton);
			leftPanel.add(viewProgramButton);
			leftPanel.add(addCritterButton);
			rightPanel.add(requestAdminButton);
			rightPanel.add(logInOutButton);
			break;
		default:
			leftPanel.add(viewLineageButton);
			leftPanel.add(viewProgramButton);
			rightPanel.add(requestUserButton);
			rightPanel.add(requestAdminButton);
			rightPanel.add(logInOutButton);
			break;
		}
	}
	
	public Dimension getMaximumSize(){
		return new Dimension(2000, 25);
	}
}
